<!DOCTYPE html>
<html lang="en">

<head>
  <base href="https://git-scm.com/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E7%BB%B4%E6%8A%A4%E9%A1%B9%E7%9B%AE" />
  <meta charset='utf-8'>
  <meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible'>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Git - 维护项目</title>

  <link href='/favicon.ico' rel='shortcut icon' type='image/x-icon'>

  <link rel="stylesheet" media="screen" href="/assets/application-a058ab010d6f86a86903175bbfdaac30ef6057e5901875616753328abbf98b2c.css" />
  <script src="/assets/modernize-b3ebe0c31c24f230dc62179d3e1030d2e57a53b1668d9382c0a27dbd44a94beb.js"></script>
  <!--[if (gte IE 6)&(lte IE 8)]>
  <script src="/javascripts/selectivizr-min.js"></script>
  <![endif]-->

</head>

<body id="documentation">

  <div class="inner">
    <header>

  <a href="/"><img src="/images/logo@2x.png" width="110" height="46" alt="Git" /></a>
  <span id="tagline"></span>
  <script type="text/javascript">
    var taglines = ["fast-version-control","everything-is-local","distributed-even-if-your-workflow-isnt","local-branching-on-the-cheap","distributed-is-the-new-centralized"];
    var tagline = taglines[Math.floor(Math.random() * taglines.length)];
    document.getElementById('tagline').innerHTML = '--' + tagline;
  </script>
  <form id="search" action="/search/results">
    <input id="search-text" name="search" placeholder="Search entire site..." autocomplete="off" type="text" />
  </form>
  <div id="search-results"></div>

</header>

  </div> <!-- .inner -->

    <div class="inner">
      <div id="content-wrapper">
        <button class="sidebar-btn"></button>
<aside class="sidebar" id="sidebar">
  <nav>
    <ul>
      <li>
        <a href="/about">About</a>
        <ul class="">
          <li>
            <a href="/about">Branching and Merging</a>
          </li>
          <li>
            <a href="/about/small-and-fast">Small and Fast</a>
          </li>
          <li>
            <a href="/about/distributed">Distributed</a>
          </li>
          <li>
            <a href="/about/info-assurance">Data Assurance</a>
          </li>
          <li>
            <a href="/about/staging-area">Staging Area</a>
          </li>
          <li>
            <a href="/about/free-and-open-source">Free and Open Source</a>
          </li>
          <li>
            <a href="/about/trademark">Trademark</a>
          </li>
        </ul>
      </li>
      <li>
        <a class="active" href="/doc">Documentation</a>
        <ul class="expanded">
          <li>
            <a href="/docs">Reference</a>
          </li>
          <li>
            <a class="active" href="/book">Book</a>
          </li>
          <li>
            <a href="/videos">Videos</a>
          </li>
          <li>
            <a href="/doc/ext">External Links</a>
          </li>
        </ul>
      </li>
      <li>
        <a href="/downloads">Downloads</a>
        <ul class="">
          <li>
            <a href="/downloads/guis">GUI Clients</a>
          </li>
          <li>
            <a href="/downloads/logos">Logos</a>
          </li>
        </ul>
      </li>
      <li>
        <a href="/community">Community</a>
      </li>
    </ul>
      <hr class="sidebar">
        <p>
This book is available in
  <a href="/book/en">English</a>.
</p>
<p>
  Full translation available in
  <table>
    <tr><td><a href="/book/az">azərbaycan dili</a>,</td></tr>
    <tr><td><a href="/book/bg">български език</a>,</td></tr>
    <tr><td><a href="/book/de">Deutsch</a>,</td></tr>
    <tr><td><a href="/book/es">Español</a>,</td></tr>
    <tr><td><a href="/book/fr">Français</a>,</td></tr>
    <tr><td><a href="/book/gr">Ελληνικά</a>,</td></tr>
    <tr><td><a href="/book/ja">日本語</a>,</td></tr>
    <tr><td><a href="/book/ko">한국어</a>,</td></tr>
    <tr><td><a href="/book/nl">Nederlands</a>,</td></tr>
    <tr><td><a href="/book/ru">Русский</a>,</td></tr>
    <tr><td><a href="/book/sl">Slovenščina</a>,</td></tr>
    <tr><td><a href="/book/tl">Tagalog</a>,</td></tr>
    <tr><td><a href="/book/uk">Українська</a></td></tr>
    <tr><td><a href="/book/zh">简体中文</a>,</td></tr>
  </table>
</p>
<p>
  Partial translations available in
  <table>
    <tr><td><a href="/book/cs">Čeština</a>,</td></tr>
    <tr><td><a href="/book/mk">Македонски</a>,</td></tr>
    <tr><td><a href="/book/pl">Polski</a>,</td></tr>
    <tr><td><a href="/book/sr">Српски</a>,</td></tr>
    <tr><td><a href="/book/uz">Ўзбекча</a>,</td></tr>
    <tr><td><a href="/book/zh-tw">繁體中文</a>,</td></tr>
  </table>
</p>
<p>
  Translations started for
  <table>
    <tr><td><a href="/book/be">Беларуская</a>,</td></tr>
    <tr><td><a href="/book/fa" dir="rtl">فارسی</a>,</td></tr>
    <tr><td><a href="/book/id">Indonesian</a>,</td></tr>
    <tr><td><a href="/book/it">Italiano</a>,</td></tr>
    <tr><td><a href="/book/ms">Bahasa Melayu</a>,</td></tr>
    <tr><td><a href="/book/pt-br">Português (Brasil)</a>,</td></tr>
    <tr><td><a href="/book/pt-pt">Português (Portugal)</a>,</td></tr>
    <tr><td><a href="/book/sv">Svenska</a>,</td></tr>
    <tr><td><a href="/book/tr">Türkçe</a>.</td></tr>
  </table>
</p>
<hr class="sidebar"/>
<p>
The source of this book is  <a href="https://github.com/progit/progit2-zh">hosted on GitHub.</a></br>
Patches, suggestions and comments are welcome.
</p>


  </nav>
</aside>

        <div id="content">
          

<div id='book-chapters'>
  <a class="dropdown-trigger" id="book-chapters-trigger" data-panel-id="chapters-dropdown" href="#">Chapters ▾</a>
<div class='dropdown-panel' id='chapters-dropdown'>
  <div class="three-column">
    <div class='column-left'>
      <ol class='book-toc'>
  <li class='chapter'>
  <h2>1. <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%85%B3%E4%BA%8E%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6">起步</a></h2>
    <ol>
        <li>
          1.1
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%85%B3%E4%BA%8E%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6" >关于版本控制 </a>
        </li>
        <li>
          1.2
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E7%AE%80%E5%8F%B2" >Git 简史 </a>
        </li>
        <li>
          1.3
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F" >Git 是什么？ </a>
        </li>
        <li>
          1.4
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%91%BD%E4%BB%A4%E8%A1%8C" >命令行 </a>
        </li>
        <li>
          1.5
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git" >安装 Git </a>
        </li>
        <li>
          1.6
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE" >初次运行 Git 前的配置 </a>
        </li>
        <li>
          1.7
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E8%8E%B7%E5%8F%96%E5%B8%AE%E5%8A%A9" >获取帮助 </a>
        </li>
        <li>
          1.8
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>2. <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7%E5%8F%96-Git-%E4%BB%93%E5%BA%93">Git 基础</a></h2>
    <ol>
        <li>
          2.1
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7%E5%8F%96-Git-%E4%BB%93%E5%BA%93" >获取 Git 仓库 </a>
        </li>
        <li>
          2.2
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%AE%B0%E5%BD%95%E6%AF%8F%E6%AC%A1%E6%9B%B4%E6%96%B0%E5%88%B0%E4%BB%93%E5%BA%93" >记录每次更新到仓库 </a>
        </li>
        <li>
          2.3
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E5%8E%86%E5%8F%B2" >查看提交历史 </a>
        </li>
        <li>
          2.4
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%92%A4%E6%B6%88%E6%93%8D%E4%BD%9C" >撤消操作 </a>
        </li>
        <li>
          2.5
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%BF%9C%E7%A8%8B%E4%BB%93%E5%BA%93%E7%9A%84%E4%BD%BF%E7%94%A8" >远程仓库的使用 </a>
        </li>
        <li>
          2.6
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%89%93%E6%A0%87%E7%AD%BE" >打标签 </a>
        </li>
        <li>
          2.7
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-Git-%E5%88%AB%E5%90%8D" >Git 别名 </a>
        </li>
        <li>
          2.8
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>3. <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B">Git 分支</a></h2>
    <ol>
        <li>
          3.1
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B" >分支简介 </a>
        </li>
        <li>
          3.2
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6" >分支的新建与合并 </a>
        </li>
        <li>
          3.3
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%A1%E7%90%86" >分支管理 </a>
        </li>
        <li>
          3.4
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E5%BC%80%E5%8F%91%E5%B7%A5%E4%BD%9C%E6%B5%81" >分支开发工作流 </a>
        </li>
        <li>
          3.5
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E8%BF%9C%E7%A8%8B%E5%88%86%E6%94%AF" >远程分支 </a>
        </li>
        <li>
          3.6
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA" >变基 </a>
        </li>
        <li>
          3.7
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>4. <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%8D%8F%E8%AE%AE">服务器上的 Git</a></h2>
    <ol>
        <li>
          4.1
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%8D%8F%E8%AE%AE" >协议 </a>
        </li>
        <li>
          4.2
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%9C%A8%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E6%90%AD%E5%BB%BA-Git" >在服务器上搭建 Git </a>
        </li>
        <li>
          4.3
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%94%9F%E6%88%90-SSH-%E5%85%AC%E9%92%A5" >生成 SSH 公钥 </a>
        </li>
        <li>
          4.4
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8" >配置服务器 </a>
        </li>
        <li>
          4.5
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-Git-%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B" >Git 守护进程 </a>
        </li>
        <li>
          4.6
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-Smart-HTTP" >Smart HTTP </a>
        </li>
        <li>
          4.7
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-GitWeb" >GitWeb </a>
        </li>
        <li>
          4.8
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-GitLab" >GitLab </a>
        </li>
        <li>
          4.9
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%AC%AC%E4%B8%89%E6%96%B9%E6%89%98%E7%AE%A1%E7%9A%84%E9%80%89%E6%8B%A9" >第三方托管的选择 </a>
        </li>
        <li>
          4.10
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>5. <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%88%86%E5%B8%83%E5%BC%8F%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B">分布式 Git</a></h2>
    <ol>
        <li>
          5.1
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%88%86%E5%B8%83%E5%BC%8F%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B" >分布式工作流程 </a>
        </li>
        <li>
          5.2
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%90%91%E4%B8%80%E4%B8%AA%E9%A1%B9%E7%9B%AE%E8%B4%A1%E7%8C%AE" >向一个项目贡献 </a>
        </li>
        <li>
          5.3
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E7%BB%B4%E6%8A%A4%E9%A1%B9%E7%9B%AE" class=active>维护项目 </a>
        </li>
        <li>
          5.4
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
</ol>

    </div>
    <div class='column-middle'>
      <ol class='book-toc'>
  <li class='chapter'>
  <h2>6. <a href="/book/zh/v2/GitHub-%E8%B4%A6%E6%88%B7%E7%9A%84%E5%88%9B%E5%BB%BA%E5%92%8C%E9%85%8D%E7%BD%AE">GitHub</a></h2>
    <ol>
        <li>
          6.1
          <a href="/book/zh/v2/GitHub-%E8%B4%A6%E6%88%B7%E7%9A%84%E5%88%9B%E5%BB%BA%E5%92%8C%E9%85%8D%E7%BD%AE" >账户的创建和配置 </a>
        </li>
        <li>
          6.2
          <a href="/book/zh/v2/GitHub-%E5%AF%B9%E9%A1%B9%E7%9B%AE%E5%81%9A%E5%87%BA%E8%B4%A1%E7%8C%AE" >对项目做出贡献 </a>
        </li>
        <li>
          6.3
          <a href="/book/zh/v2/GitHub-%E7%BB%B4%E6%8A%A4%E9%A1%B9%E7%9B%AE" >维护项目 </a>
        </li>
        <li>
          6.4
          <a href="/book/zh/v2/GitHub-%E7%AE%A1%E7%90%86%E7%BB%84%E7%BB%87" >管理组织 </a>
        </li>
        <li>
          6.5
          <a href="/book/zh/v2/GitHub-%E8%84%9A%E6%9C%AC-GitHub" >脚本 GitHub </a>
        </li>
        <li>
          6.6
          <a href="/book/zh/v2/GitHub-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>7. <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC">Git 工具</a></h2>
    <ol>
        <li>
          7.1
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC" >选择修订版本 </a>
        </li>
        <li>
          7.2
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E4%BA%A4%E4%BA%92%E5%BC%8F%E6%9A%82%E5%AD%98" >交互式暂存 </a>
        </li>
        <li>
          7.3
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E8%B4%AE%E8%97%8F%E4%B8%8E%E6%B8%85%E7%90%86" >贮藏与清理 </a>
        </li>
        <li>
          7.4
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E7%AD%BE%E7%BD%B2%E5%B7%A5%E4%BD%9C" >签署工作 </a>
        </li>
        <li>
          7.5
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%90%9C%E7%B4%A2" >搜索 </a>
        </li>
        <li>
          7.6
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E5%86%99%E5%8E%86%E5%8F%B2" >重写历史 </a>
        </li>
        <li>
          7.7
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86" >重置揭密 </a>
        </li>
        <li>
          7.8
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%AB%98%E7%BA%A7%E5%90%88%E5%B9%B6" >高级合并 </a>
        </li>
        <li>
          7.9
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-Rerere" >Rerere </a>
        </li>
        <li>
          7.10
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E4%BD%BF%E7%94%A8-Git-%E8%B0%83%E8%AF%95" >使用 Git 调试 </a>
        </li>
        <li>
          7.11
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97" >子模块 </a>
        </li>
        <li>
          7.12
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%89%93%E5%8C%85" >打包 </a>
        </li>
        <li>
          7.13
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%9B%BF%E6%8D%A2" >替换 </a>
        </li>
        <li>
          7.14
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%87%AD%E8%AF%81%E5%AD%98%E5%82%A8" >凭证存储 </a>
        </li>
        <li>
          7.15
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>8. <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git">自定义 Git</a></h2>
    <ol>
        <li>
          8.1
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git" >配置 Git </a>
        </li>
        <li>
          8.2
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E5%B1%9E%E6%80%A7" >Git 属性 </a>
        </li>
        <li>
          8.3
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90" >Git 钩子 </a>
        </li>
        <li>
          8.4
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E4%BD%BF%E7%94%A8%E5%BC%BA%E5%88%B6%E7%AD%96%E7%95%A5%E7%9A%84%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90" >使用强制策略的一个例子 </a>
        </li>
        <li>
          8.5
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>9. <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E4%BD%9C%E4%B8%BA%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84-Git">Git 与其他系统</a></h2>
    <ol>
        <li>
          9.1
          <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E4%BD%9C%E4%B8%BA%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84-Git" >作为客户端的 Git </a>
        </li>
        <li>
          9.2
          <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E8%BF%81%E7%A7%BB%E5%88%B0-Git" >迁移到 Git </a>
        </li>
        <li>
          9.3
          <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>10. <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4%E4%B8%8E%E4%B8%8A%E5%B1%82%E5%91%BD%E4%BB%A4">Git 内部原理</a></h2>
    <ol>
        <li>
          10.1
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4%E4%B8%8E%E4%B8%8A%E5%B1%82%E5%91%BD%E4%BB%A4" >底层命令与上层命令 </a>
        </li>
        <li>
          10.2
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1" >Git 对象 </a>
        </li>
        <li>
          10.3
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%BC%95%E7%94%A8" >Git 引用 </a>
        </li>
        <li>
          10.4
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%8C%85%E6%96%87%E4%BB%B6" >包文件 </a>
        </li>
        <li>
          10.5
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BC%95%E7%94%A8%E8%A7%84%E8%8C%83" >引用规范 </a>
        </li>
        <li>
          10.6
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE" >传输协议 </a>
        </li>
        <li>
          10.7
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E7%BB%B4%E6%8A%A4%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%81%A2%E5%A4%8D" >维护与数据恢复 </a>
        </li>
        <li>
          10.8
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F" >环境变量 </a>
        </li>
        <li>
          10.9
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
</ol>

    </div>
    <div class='column-right'>
      <ol class='book-toc'>
  <li class='chapter'>
  <h2>A1. <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2">附录 A: 在其它环境中使用 Git</a></h2>
    <ol>
        <li>
          A1.1
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2" >图形界面 </a>
        </li>
        <li>
          A1.2
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Visual-Studio-%E4%B8%AD%E7%9A%84-Git" >Visual Studio 中的 Git </a>
        </li>
        <li>
          A1.3
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Visual-Studio-Code-%E4%B8%AD%E7%9A%84-Git" >Visual Studio Code 中的 Git </a>
        </li>
        <li>
          A1.4
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Eclipse-%E4%B8%AD%E7%9A%84-Git" >Eclipse 中的 Git </a>
        </li>
        <li>
          A1.5
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-IntelliJ-%2F-PyCharm-%2F-WebStorm-%2F-PhpStorm-%2F-RubyMine-%E4%B8%AD%E7%9A%84-Git" >IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git </a>
        </li>
        <li>
          A1.6
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Sublime-Text-%E4%B8%AD%E7%9A%84-Git" >Sublime Text 中的 Git </a>
        </li>
        <li>
          A1.7
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Bash-%E4%B8%AD%E7%9A%84-Git" >Bash 中的 Git </a>
        </li>
        <li>
          A1.8
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Zsh-%E4%B8%AD%E7%9A%84-Git" >Zsh 中的 Git </a>
        </li>
        <li>
          A1.9
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Git-%E5%9C%A8-PowerShell-%E4%B8%AD%E4%BD%BF%E7%94%A8-Git" >Git 在 PowerShell 中使用 Git </a>
        </li>
        <li>
          A1.10
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>A2. <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-%E5%91%BD%E4%BB%A4%E8%A1%8C-Git-%E6%96%B9%E5%BC%8F">附录 B: 在你的应用中嵌入 Git</a></h2>
    <ol>
        <li>
          A2.1
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-%E5%91%BD%E4%BB%A4%E8%A1%8C-Git-%E6%96%B9%E5%BC%8F" >命令行 Git 方式 </a>
        </li>
        <li>
          A2.2
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-Libgit2" >Libgit2 </a>
        </li>
        <li>
          A2.3
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-JGit" >JGit </a>
        </li>
        <li>
          A2.4
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-go-git" >go-git </a>
        </li>
        <li>
          A2.5
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-Dulwich" >Dulwich </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>A3. <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%AE%BE%E7%BD%AE%E4%B8%8E%E9%85%8D%E7%BD%AE">附录 C: Git 命令</a></h2>
    <ol>
        <li>
          A3.1
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%AE%BE%E7%BD%AE%E4%B8%8E%E9%85%8D%E7%BD%AE" >设置与配置 </a>
        </li>
        <li>
          A3.2
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%8E%B7%E5%8F%96%E4%B8%8E%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE" >获取与创建项目 </a>
        </li>
        <li>
          A3.3
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%BF%AB%E7%85%A7%E5%9F%BA%E7%A1%80" >快照基础 </a>
        </li>
        <li>
          A3.4
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%88%86%E6%94%AF%E4%B8%8E%E5%90%88%E5%B9%B6" >分支与合并 </a>
        </li>
        <li>
          A3.5
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E9%A1%B9%E7%9B%AE%E5%88%86%E4%BA%AB%E4%B8%8E%E6%9B%B4%E6%96%B0" >项目分享与更新 </a>
        </li>
        <li>
          A3.6
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E6%A3%80%E6%9F%A5%E4%B8%8E%E6%AF%94%E8%BE%83" >检查与比较 </a>
        </li>
        <li>
          A3.7
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%B0%83%E8%AF%95" >调试 </a>
        </li>
        <li>
          A3.8
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%A1%A5%E4%B8%81" >补丁 </a>
        </li>
        <li>
          A3.9
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E9%82%AE%E4%BB%B6" >邮件 </a>
        </li>
        <li>
          A3.10
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%A4%96%E9%83%A8%E7%B3%BB%E7%BB%9F" >外部系统 </a>
        </li>
        <li>
          A3.11
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E7%AE%A1%E7%90%86" >管理 </a>
        </li>
        <li>
          A3.12
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4" >底层命令 </a>
        </li>
    </ol>
  </li>
</ol>

    </div>
  </div>
 </div>

    <span class="light" id="edition">
      2nd Edition
    </span>
</div>

<div id='main' class="book edition2">
    <h1>5.3 分布式 Git - 维护项目</h1>
  <div>
<h2 id="_维护项目">维护项目</h2>
<div class="paragraph">
<p>
除了如何有效地参与一个项目的贡献之外，你可能也需要了解如何维护项目。
这包含接受并应用别人使用 <code>format-patch</code> 生成并通过电子邮件发送过来的补丁，
或对项目添加的远程版本库分支中的更改进行整合。
但无论是管理版本库，还是帮忙验证、审核收到的补丁，都需要同其他贡献者约定某种长期可持续的工作方式。</p>
</div>
<div class="sect3">
<h3 id="_在主题分支中工作">在主题分支中工作</h3>
<div class="paragraph">
<p>
如果你想向项目中整合一些新东西，最好将这些尝试局限在 <strong>主题分支</strong>——一种通常用来尝试新东西的临时分支中。
这样便于单独调整补丁，如果遇到无法正常工作的情况，可以先不用管，等到有时间的时候再来处理。
如果你基于你所尝试进行工作的特性为分支创建一个简单的名字，比如 <code>ruby_client</code> 或者具有类似描述性的其他名字，这样即使你必须暂时抛弃它，以后回来时也不会忘记。
项目的维护者一般还会为这些分支附带命名空间，比如 <code>sc/ruby_client</code>（其中 <code>sc</code> 是贡献该项工作的人名称的简写）。
你应该记得，可以使用如下方式基于 <code>master</code> 分支建立主题分支：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git branch sc/ruby_client master</code></pre>
</div>
</div>
<div class="paragraph">
<p>或者如果你同时想立刻切换到新分支上的话，可以使用 <code>checkout -b</code> 选项：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git checkout -b sc/ruby_client master</code></pre>
</div>
</div>
<div class="paragraph">
<p>现在你已经准备好将你收到的贡献加入到这个主题分支，并考虑是否将其合并到长期分支中去了。</p>
</div>
</div>
<div class="sect3">
<h3 id="_patches_from_email">应用来自邮件的补丁</h3>
<div class="paragraph">
<p>
如果你通过电子邮件收到了一个需要整合进入项目的补丁，你需要将其应用到主题分支中进行评估。
有两种应用该种补丁的方法：使用 <code>git apply</code>，或者使用 <code>git am</code>。</p>
</div>
<div class="sect4">
<h4 id="_使用_apply_命令应用补丁">使用 <code>apply</code> 命令应用补丁</h4>
<div class="paragraph">
<p>
如果你收到了一个使用 <code>git diff</code> 或 Unix <code>diff</code> 命令的变体（不推荐使用这种方式，具体见下一节）
创建的补丁，可以使用 <code>git apply</code> 命令来应用。
假设你将补丁保存在了 <code>/tmp/patch-ruby-client.patch</code> 中，可以这样应用补丁：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git apply /tmp/patch-ruby-client.patch</code></pre>
</div>
</div>
<div class="paragraph">
<p>这会修改工作目录中的文件。
它与运行 <code>patch -p1</code> 命令来应用补丁几乎是等效的，但是这种方式更加严格，相对于 patch 来说，它能够接受的模糊匹配更少。
它也能够处理 <code>git diff</code> 格式文件所描述的文件添加、删除和重命名操作，而 <code>patch</code> 则不会。
最后，<code>git apply</code> 命令采用了一种“全部应用，否则就全部撤销（apply all or abort all）”的模型，
即补丁只有全部内容都被应用和完全不被应用两个状态，而 <code>patch</code> 可能会导致补丁文件被部分应用，
最后使你的工作目录保持在一个比较奇怪的状态。
总体来看，<code>git apply</code> 命令要比 <code>patch</code> 谨慎得多。
并且，它不会为你创建提交——在运行之后，你需要手动暂存并提交补丁所引入的更改。</p>
</div>
<div class="paragraph">
<p>在实际应用补丁前，你还可以使用 git apply 来检查补丁是否可以顺利应用——即对补丁运行 <code>git apply --check</code> 命令：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git apply --check 0001-seeing-if-this-helps-the-gem.patch
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果没有产生输出，则该补丁可以顺利应用。
如果检查失败了，该命令还会以一个非零的状态退出，所以需要时你也可以在脚本中使用它。</p>
</div>
</div>
<div class="sect4">
<h4 id="_git_am">使用 <code>am</code> 命令应用补丁</h4>
<div class="paragraph">
<p>
如果补丁的贡献者也是一个 Git 用户，并且其能熟练使用 <code>format-patch</code> 命令来生成补丁，这样的话你的工作会变得更加轻松，因为这种补丁中包含了作者信息和提交信息供你参考。
如果可能的话，请鼓励贡献者使用 <code>format-patch</code> 而不是 <code>diff</code> 来为你生成补丁。
而只有对老式的补丁，你才必须使用 <code>git apply</code> 命令。</p>
</div>
<div class="paragraph">
<p>要应用一个由 <code>format-patch</code> 命令生成的补丁，你应该使用 <code>git am</code> 命令
（该命令的名字 <code>am</code> 表示它“应用（Apply）一系列来自邮箱（Mailbox）的补丁”）。
从技术的角度看，<code>git am</code> 是为了读取 mbox 文件而构建的，
mbox 是一种用来在单个文本文件中存储一个或多个电子邮件消息的简单纯文本格式。
其大致格式如下所示：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
From: Jessica Smith &lt;jessica@example.com&gt;
Date: Sun, 6 Apr 2008 10:17:23 -0700
Subject: [PATCH 1/2] add limit to log function

Limit log functionality to the first 20</code></pre>
</div>
</div>
<div class="paragraph">
<p>这其实就是你前面看到的 <code>git format-patch</code> 命令输出的开始几行，
而同时它也是有效的 mbox 电子邮件格式。
如果有人使用 <code>git send-email</code> 命令将补丁以电子邮件的形式发送给你，
你便可以将它下载为 mbox 格式的文件，之后将 git am 命令指向该文件，它会应用其中包含的所有补丁。
如果你所使用的邮件客户端能够同时将多封邮件保存为 mbox 格式的文件，
你甚至能够将一系列补丁打包为单个 mbox 文件，并利用 <code>git am</code> 命令将它们一次性全部应用。</p>
</div>
<div class="paragraph">
<p>然而，如果贡献者将 <code>git format-patch</code> 生成的补丁文件上传到工单系统或类似的任务处理系统，
你可以先将其保存到本地，之后通过 <code>git am</code> 来应用补丁：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git am 0001-limit-log-function.patch
Applying: add limit to log function</code></pre>
</div>
</div>
<div class="paragraph">
<p>你会看到补丁被顺利地应用，并且为你自动创建了一个新的提交。
其中的作者信息来自于电子邮件头部的 <code>From</code> 和 <code>Date</code> 字段，提交消息则取自 <code>Subject</code> 和邮件正文中补丁之前的内容。
比如，应用上面那个 mbox 示例后生成的提交是这样的：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git log --pretty=fuller -1
commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
Author:     Jessica Smith &lt;jessica@example.com&gt;
AuthorDate: Sun Apr 6 10:17:23 2008 -0700
Commit:     Scott Chacon &lt;schacon@gmail.com&gt;
CommitDate: Thu Apr 9 09:19:06 2009 -0700

   add limit to log function

   Limit log functionality to the first 20</code></pre>
</div>
</div>
<div class="paragraph">
<p>其中 <code>Commit</code> 信息表示的是应用补丁的人和应用补丁的时间。
<code>Author</code> 信息则表示补丁的原作者和原本的创建时间。</p>
</div>
<div class="paragraph">
<p>但是，有时候无法顺利地应用补丁。
这也许是因为你的主分支和创建补丁的分支相差较多，也有可能是因为这个补丁依赖于其他你尚未应用的补丁。
这种情况下，<code>git am</code> 进程将会报错并且询问你要做什么：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git am 0001-seeing-if-this-helps-the-gem.patch
Applying: seeing if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Patch failed at 0001.
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".</code></pre>
</div>
</div>
<div class="paragraph">
<p>该命令将会在所有出现问题的文件内加入冲突标记，就和发生冲突的合并或变基操作一样。
而你解决问题的手段很大程度上也是一样的——即手动编辑那些文件来解决冲突，暂存新的文件，
之后运行 <code>git am --resolved</code> 继续应用下一个补丁：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ (fix the file)
$ git add ticgit.gemspec
$ git am --resolved
Applying: seeing if this helps the gem</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果你希望 Git 能够尝试以更加智能的方式解决冲突，你可以对其传递 <code>-3</code> 选项来使 Git 尝试进行三方合并。
该选项默认并没有打开，因为如果用于创建补丁的提交并不在你的版本库内的话，这样做是没有用处的。
而如果你确实有那个提交的话——比如补丁是基于某个公共提交的——那么通常 <code>-3</code> 选项对于应用有冲突的补丁是更加明智的选择。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git am -3 0001-seeing-if-this-helps-the-gem.patch
Applying: seeing if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.</code></pre>
</div>
</div>
<div class="paragraph">
<p>比如上面这种情况，如果没有 <code>-3</code> 选项的话，这看起来就像是存在一个冲突。
由于使用了 <code>-3</code> 选项，该补丁就被干净地应用了</p>
</div>
<div class="paragraph">
<p>如果你正在利用一个 mbox 文件应用多个补丁，也可以在交互模式下运行 <code>am</code> 命令，
这样在每个补丁之前，它会停住询问你是否要应用该补丁：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git am -3 -i mbox
Commit Body is:
--------------------------
seeing if this helps the gem
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all</code></pre>
</div>
</div>
<div class="paragraph">
<p>这在你保存的补丁较多时很好用，因为你可以在应用之前查看忘掉内容的补丁，并且跳过已经应用过的补丁。</p>
</div>
<div class="paragraph">
<p>当与你的特性相关的所有补丁都被应用并提交到分支中之后，你就可以选择是否以及如何将其整合到更长期的分支中去了。</p>
</div>
</div>
</div>
<div class="sect3">
<h3 id="_checking_out_remotes">检出远程分支</h3>
<div class="paragraph">
<p>
如果你的贡献者建立了自己的版本库，并且向其中推送了若干修改，
之后将版本库的 URL 和包含更改的远程分支发送给你，那么你可以将其添加为一个远程分支，并且在本地进行合并。</p>
</div>
<div class="paragraph">
<p>比如 Jessica 向你发送了一封电子邮件，内容是在她的版本库中的 <code>ruby-client</code> 分支中有一个很不错的新功能，
为了测试该功能，你可以将其添加为一个远程分支，并在本地检出：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git remote add jessica git://github.com/jessica/myproject.git
$ git fetch jessica
$ git checkout -b rubyclient jessica/ruby-client</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果她再次发邮件说另一个分支中包含另一个优秀功能，因为之前已经设置好远程分支了，
你就可以直接进行 <code>fetch</code> 和 <code>checkout</code> 操作。</p>
</div>
<div class="paragraph">
<p>这对于与他人长期合作工作来说很有用。
而对于提交补丁频率较小的贡献者，相对于每个人维护自己的服务器，不断增删远程分支的做法，使用电子邮件来接收可能会比较省时。
况且你也不会想要加入数百个只提供一两个补丁的远程分支。
然而，脚本和托管服务在一定程度上可以简化这些工作——这很大程度上依赖于你和你的贡献者开发的方式。</p>
</div>
<div class="paragraph">
<p>这种方式的另一种优点是你可以同时得到提交历史。
虽然代码合并中可能会出现问题，但是你能获知他人的工作是基于你的历史中的具体哪一个位置；所以 Git 会默认进行三方合并，不需要提供 <code>-3</code> 选项，你也不需要担心补丁是基于某个你无法访问的提交生成的。</p>
</div>
<div class="paragraph">
<p>对于非持续性的合作，如果你依然想要以这种方式拉取数据的话，你可以对远程版本库的 URL 调用 <code>git pull</code> 命令。
这会执行一个一次性的抓取，而不会将该 URL 存为远程引用：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git pull https://github.com/onetimeguy/project
From https://github.com/onetimeguy/project
 * branch            HEAD       -&gt; FETCH_HEAD
Merge made by the 'recursive' strategy.</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h3 id="_what_is_introduced">确定引入了哪些东西</h3>
<div class="paragraph">
<p>
你已经有了一个包含其他人贡献的主题分支。
现在你可以决定如何处理它们了。
本节回顾了若干命令，以便于你检查若将其合并入主分支所引入的更改。</p>
</div>
<div class="paragraph">
<p>一般来说，你应该对该分支中所有 <code>master</code> 分支尚未包含的提交进行检查。
通过在分支名称前加入 <code>--not</code> 选项，你可以排除 <code>master</code> 分支中的提交。
这和我们之前使用的 <code>master..contrib</code> 格式是一样的。
假设贡献者向你发送了两个补丁，为此你创建了一个名叫 <code>contrib</code> 的分支并在其上应用补丁，你可以运行：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git log contrib --not master
commit 5b6235bd297351589efc4d73316f0a68d484f118
Author: Scott Chacon &lt;schacon@gmail.com&gt;
Date:   Fri Oct 24 09:53:59 2008 -0700

    seeing if this helps the gem

commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
Author: Scott Chacon &lt;schacon@gmail.com&gt;
Date:   Mon Oct 22 19:38:36 2008 -0700

    updated the gemspec to hopefully work better</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果要查看每次提交所引入的具体修改，你应该记得可以给 <code>git log</code> 命令传递 <code>-p</code> 选项，这样它会在每次提交后面附加对应的差异（diff）。</p>
</div>
<div class="paragraph">
<p>而要查看将该主题分支与另一个分支合并的完整 diff，你可能需要使用一个有些奇怪的技巧来得到正确的结果。
你可能会想到这种方式：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git diff master</code></pre>
</div>
</div>
<div class="paragraph">
<p>这个命令会输出一个 diff，但它可能并不是我们想要的。
如果在你创建主题分支之后，<code>master</code> 分支向前移动了，你获得的结果就会显得有些不对。
这是因为 Git 会直接将该主题分支与 <code>master</code> 分支的最新提交快照进行比较。
比如说你在 <code>master</code> 分支中向某个文件添加了一行内容，那么直接比对最新快照的结果看上去就像是你在主题分支中将这一行删除了。</p>
</div>
<div class="paragraph">
<p>如果 <code>master</code> 分支是你的主题分支的直接祖先，其实是没有任何问题的；
但是一旦两个分支的历史产生了分叉，上述比对产生的 diff 看上去就像是将主题分支中所有的新东西加入，
并且将 <code>master</code> 分支所独有的东西删除。</p>
</div>
<div class="paragraph">
<p>而你真正想要检查的东西，实际上仅仅是主题分支所添加的更改——也就是该分支与 <code>master</code> 分支合并所要引入的工作。
要达到此目的，你需要让 Git 对主题分支上最新的提交与该分支与 <code>master</code> 分支的首个公共祖先进行比较。</p>
</div>
<div class="paragraph">
<p>从技术的角度讲，你可以以手工的方式找出公共祖先，并对其显式运行 diff 命令：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git merge-base contrib master
36c7dba2c95e6bbb78dfa822519ecfec6e1ca649
$ git diff 36c7db</code></pre>
</div>
</div>
<div class="paragraph">
<p>或者，更简洁的形式：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git diff $(git merge-base contrib master)</code></pre>
</div>
</div>
<div class="paragraph">
<p>然而，这种做法比较麻烦，所以 Git 提供了一种比较便捷的方式：三点语法。
对于 <code>git diff</code> 命令来说，你可以通过把 <code>…​</code> 置于另一个分支名后来对该分支的最新提交与两个分支的共同祖先进行比较：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git diff master...contrib</code></pre>
</div>
</div>
<div class="paragraph">
<p>该命令仅会显示自当前主题分支与 <code>master</code> 分支的共同祖先起，该分支中的工作。
这个语法很有用，应该牢记。</p>
</div>
</div>
<div class="sect3">
<h3 id="_将贡献的工作整合进来">将贡献的工作整合进来</h3>
<div class="paragraph">
<p>
当主题分支中所有的工作都已经准备好整合进入更靠近主线的分支时，接下来的问题就是如何进行整合了。
此外，还有一个问题是，你想使用怎样的总体工作流来维护你的项目？
你的选择有很多，我们会介绍其中的一部分。</p>
</div>
<div class="sect4">
<h4 id="_合并工作流">合并工作流</h4>
<div class="paragraph">
<p>
一种基本的工作流就是将所有的工作直接合并到 <code>master</code> 分支。
在这种情况下，<code>master</code> 分支包含的代码是基本稳定的。
当你完成某个主题分支的工作，或审核通过了其他人所贡献的工作时，你会将其合并进入 <code>master</code> 分支，之后将主题分支删除，如此反复。</p>
</div>
<div class="paragraph">
<p>举例来说，如果我们的版本库包含类似 <a href="ch00/merwf_a">包含若干主题分支的提交历史。</a> 的两个名称分别为 <code>ruby_client</code> 和 <code>php_client</code> 的分支，
并且我们合并完 <code>ruby_client</code> 分支后，再合并 <code>php_client</code> 分支，那么提交历史最后会变成 <a href="ch00/merwf_b">合并主题分支之后。</a> 的样子。</p>
</div>
<div id="merwf_a" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/merging-workflows-1.png" alt="包含若干主题分支的提交历史。">
</div>
<div class="title">Figure 73. 包含若干主题分支的提交历史。</div>
</div>
<div id="merwf_b" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/merging-workflows-2.png" alt="合并主题分支之后。">
</div>
<div class="title">Figure 74. 合并主题分支之后。</div>
</div>
<div class="paragraph">
<p>这也许是最简单的工作流了，但是当项目更大，或更稳定，你对自己所引入的工作更加在意时，它可能会带来问题。</p>
</div>
<div class="paragraph">
<p>如果你的项目非常重要，你可能会使用两阶段合并循环。
在这种情况下，你会维护两个长期分支，分别是 <code>master</code> 和 <code>develop</code>，<code>master</code> 分支只会在一个非常稳定的版本发布时才会更新，而所有的新代码会首先整合进入 <code>develop</code> 分支。
你定期将这两个分支推送到公共版本库中。
每次需要合并新的主题分支时（<a href="ch00/merwf_c">合并主题分支前。</a>），你都应该合并进入 <code>develop</code> 分支（<a href="ch00/merwf_d">合并主题分支后。</a>）；当打标签发布的时候，你会将 <code>master</code> 分支快进到已经稳定的 <code>develop</code> 分支（<a href="ch00/merwf_e">一次发布之后。</a>）。</p>
</div>
<div id="merwf_c" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/merging-workflows-3.png" alt="合并主题分支前。">
</div>
<div class="title">Figure 75. 合并主题分支前。</div>
</div>
<div id="merwf_d" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/merging-workflows-4.png" alt="合并主题分支后。">
</div>
<div class="title">Figure 76. 合并主题分支后。</div>
</div>
<div id="merwf_e" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/merging-workflows-5.png" alt="一次发布之后。">
</div>
<div class="title">Figure 77. 一次发布之后。</div>
</div>
<div class="paragraph">
<p>这样当人们克隆你项目的版本库后，既可以检出 <code>master</code> 分支以构建最新的稳定版本并保持更新，
也可以检出包含更多前沿内容 <code>develop</code> 分支。
你也可以扩展这个概念，维护一个将所有工作合并到一起的整合分支。
当该分支的代码稳定并通过测试之后，将其合并进入 <code>develop</code> 分支；
经过一段时间，确认其稳定之后，将其以快进的形式并入 <code>master</code> 分支。</p>
</div>
</div>
<div class="sect4">
<h4 id="_大项目合并工作流">大项目合并工作流</h4>
<div class="paragraph">
<p>
Git 项目包含四个长期分支：<code>master</code>、<code>next</code>，用于新工作的 <code>pu</code>（proposed updates）和用于维护性向后移植工作（maintenance backports）的 <code>maint</code> 分支。
贡献者的新工作会以类似之前所介绍的方式收入主题分支中（见 <a href="ch00/merwf_f">管理复杂的一系列接收贡献的平行主题分支。</a>）。
之后对主题分支进行测试评估，检查其是否已经能够合并，或者仍需要更多工作。
安全的主题分支会被合并入 <code>next</code> 分支，之后该分支会被推送使得所有人都可以尝试整合到一起的特性。</p>
</div>
<div id="merwf_f" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/large-merges-1.png" alt="管理复杂的一系列接收贡献的平行主题分支。">
</div>
<div class="title">Figure 78. 管理复杂的一系列接收贡献的平行主题分支。</div>
</div>
<div class="paragraph">
<p>如果主题分支需要更多工作，它则会被并入 <code>pu</code> 分支。
当它们完全稳定之后，会被再次并入 <code>master</code> 分支。
这意味着 <code>master</code> 分支始终在进行快进，<code>next</code> 分支偶尔会被变基，而 <code>pu</code> 分支的变基比较频繁：</p>
</div>
<div class="imageblock">
<div class="content">
<img src="/book/en/v2/images/large-merges-2.png" alt="将贡献的主题分支并入长期整合分支。">
</div>
<div class="title">Figure 79. 将贡献的主题分支并入长期整合分支。</div>
</div>
<div class="paragraph">
<p>当主题分支最终被并入 <code>master</code> 分支后，便会被从版本库中删除掉。
Git 项目还有一个从上一次发布中派生出来的 <code>maint</code> 分支来提供向后移植过来的补丁以供发布维护更新。
因此，当你克隆 Git 的版本库之后，就会有四个可分别评估该项目开发的不同阶段的可检出的分支，
检出哪个分支，取决于你需要多新的版本，或者你想要如何进行贡献；
对于维护者来说，这套结构化的工作流能帮助它们审查新的贡献。
Git 项目的工作流是特别的。要清晰地理解它，请阅读
<a href="https://github.com/git/git/blob/master/Documentation/howto/maintain-git.txt">Git 维护者手册</a>。</p>
</div>
</div>
<div class="sect4">
<h4 id="_rebase_cherry_pick">变基与拣选工作流</h4>
<div class="paragraph">
<p>
为了保持线性的提交历史，有些维护者更喜欢在 <code>master</code> 分支上对贡献过来的工作进行变基和拣选，而不是直接将其合并。
当你完成了某个主题分支中的工作，并且决定要将其整合的时候，你可以在该分支中运行变基命令，
在当前 <code>master</code> 分支（或者是 <code>develop</code> 等分支）的基础上重新构造修改。
如果结果理想的话，你可以快进 <code>master</code> 分支，最后得到一个线性的项目提交历史。</p>
</div>
<div class="paragraph">
<p>
另一种将引入的工作转移到其他分支的方法是拣选。
Git 中的拣选类似于对特定的某次提交的变基。
它会提取该提交的补丁，之后尝试将其重新应用到当前分支上。
这种方式在你只想引入主题分支中的某个提交，或者主题分支中只有一个提交，而你不想运行变基时很有用。
举个例子，假设你的项目提交历史类似：</p>
</div>
<div class="imageblock">
<div class="content">
<img src="/book/en/v2/images/rebasing-1.png" alt="拣选之前的示例历史。">
</div>
<div class="title">Figure 80. 拣选之前的示例历史。</div>
</div>
<div class="paragraph">
<p>如果你希望将提交 <code>e43a6</code> 拉取到 <code>master</code> 分支，你可以运行：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git cherry-pick e43a6
Finished one cherry-pick.
[master]: created a0a41a9: "More friendly message when locking the index fails."
 3 files changed, 17 insertions(+), 3 deletions(-)</code></pre>
</div>
</div>
<div class="paragraph">
<p>这样会拉取和 <code>e43a6</code> 相同的更改，但是因为应用的日期不同，你会得到一个新的提交 SHA-1 值。
现在你的历史会变成这样：</p>
</div>
<div class="imageblock">
<div class="content">
<img src="/book/en/v2/images/rebasing-2.png" alt="拣选主题分支中的一个提交后的历史。">
</div>
<div class="title">Figure 81. 拣选主题分支中的一个提交后的历史。</div>
</div>
<div class="paragraph">
<p>现在你可以删除这个主题分支，并丢弃不想拉入的提交。</p>
</div>
</div>
<div class="sect4">
<h4 id="_rerere">Rerere</h4>
<div class="paragraph">
<p>
如果你在进行大量的合并或变基，或维护一个长期的主题分支，Git 提供的一个叫做“rerere”的功能会有一些帮助。</p>
</div>
<div class="paragraph">
<p>Rerere 是“重用已记录的冲突解决方案（reuse recorded resolution）”的意思——它是一种简化冲突解决的方法。
当启用 rerere 时，Git 将会维护一些成功合并之前和之后的镜像，当 Git 发现之前已经修复过类似的冲突时，
便会使用之前的修复方案，而不需要你的干预。</p>
</div>
<div class="paragraph">
<p>这个功能包含两个部分：一个配置选项和一个命令。
其中的配置选项是 <code>rerere.enabled</code>，把它放在全局配置中就可以了：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git config --global rerere.enabled true</code></pre>
</div>
</div>
<div class="paragraph">
<p>现在每当你进行一次需要解决冲突的合并时，解决方案都会被记录在缓存中，以备之后使用。</p>
</div>
<div class="paragraph">
<p>如果你需要和 rerere 的缓存交互，你可以使用 <code>git rerere</code> 命令。
当单独调用它时，Git 会检查解决方案数据库，尝试寻找一个和当前任一冲突相关的匹配项并解决冲突
（尽管当 <code>rerere.enabled</code> 被设置为 <code>true</code> 时会自动进行）。
它也有若干子命令，可用来查看记录项，删除特定解决方案和清除缓存全部内容等。
我们将在 <a href="ch00/ef_rerere">Rerere</a> 中详细探讨。</p>
</div>
</div>
</div>
<div class="sect3">
<h3 id="_tagging_releases">为发布打标签</h3>
<div class="paragraph">
<p>
当你决定进行一次发布时，你可能想要打一个标签，这样在之后的任何一个提交点都可以重新创建该发布。
你在 <a href="ch00/ch02-git-basics-chapter">Git 基础</a> 中已经了解了创建新标签的过程。
作为一个维护者，如果你决定要为标签签名的话，打标签的过程应该是这样子的：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Scott Chacon &lt;schacon@gmail.com&gt;"
1024-bit DSA key, ID F721C45A, created 2009-02-09</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果你为标签签名了，你可能会遇到分发用来签名的 PGP 公钥的问题。
Git 项目的维护者已经解决了这一问题，其方法是在版本库中以 blob 对象的形式包含他们的公钥，并添加一个直接指向该内容的标签。
要完成这一任务，首先你可以通过运行 <code>gpg --list-keys</code> 找出你所想要的 key：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09]
uid                  Scott Chacon &lt;schacon@gmail.com&gt;
sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09]</code></pre>
</div>
</div>
<div class="paragraph">
<p>之后你可以通过导出 key 并通过管道传递给 <code>git hash-object</code> 来直接将 key 导入到 Git 的数据库中，<code>git hash-object</code> 命令会向 Git 中写入一个包含其内容的新 blob 对象，并向你返回该 blob 对象的 SHA-1 值：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ gpg -a --export F721C45A | git hash-object -w --stdin
659ef797d181633c87ec71ac3f9ba29fe5775b92</code></pre>
</div>
</div>
<div class="paragraph">
<p>既然 Git 中已经包含你的 key 的内容了，你就可以通过指定由 <code>hash-object</code> 命令给出的新 SHA-1 值来创建一个直接指向它的标签：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果你运行 <code>git push --tags</code> 命令，那么 <code>maintainer-pgp-pub</code> 标签将会被共享给所有人。
需要校验标签的人可以通过从数据库中直接拉取 blob 对象并导入到 GPG 中来导入 PGP key：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git show maintainer-pgp-pub | gpg --import</code></pre>
</div>
</div>
<div class="paragraph">
<p>人们可以使用这个 key 来校验所有由你签名的标签。
另外，如果你在标签信息中包含了一些操作说明，用户可以通过运行 <code>git show &lt;tag&gt;</code> 来获取更多关于标签校验的说明。</p>
</div>
</div>
<div class="sect3">
<h3 id="_build_number">生成一个构建号</h3>
<div class="paragraph">
<p>
Git 中不存在随每次提交递增的“v123”之类的数字序列，如果你想要为提交附上一个可读的名称，
可以对其运行 <code>git describe</code> 命令。作为回应，Git 将会生成一个字符串，
它由最近的标签名、自该标签之后的提交数目和你所描述的提交的部分 SHA-1 值（前缀的 <code>g</code> 表示 Git）构成：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git describe master
v1.6.2-rc1-20-g8c5b85c</code></pre>
</div>
</div>
<div class="paragraph">
<p>这样你在导出一个快照或构建时，可以给出一个便于人们理解的命名。
实际上，如果你的 Git 是从 Git 自己的版本库克隆下来并构建的，那么 <code>git --version</code> 命令给出的结果是与此类似的。
如果你所描述的提交自身就有一个标签，那么它将只会输出标签名，没有后面两项信息。</p>
</div>
<div class="paragraph">
<p>默认情况下， <code>git describe</code> 命令需要有注解的标签（即使用 <code>-a</code> 或 <code>-s</code> 选项创建的标签）；
如果你想使用轻量标签（无注解的标签），请在命令后添加 <code>--tags</code> 选项。
你也可以使用这个字符串来调用 <code>git checkout</code> 或 <code>git show</code> 命令，
但是这依赖于其末尾的简短 SHA-1 值，因此不一定一直有效。
比如，最近 Linux 内核为了保证 SHA-1 值对象的唯一性，将其位数由 8 位扩展到了 10 位，
导致以前的 <code>git describe</code> 输出全部失效。</p>
</div>
</div>
<div class="sect3">
<h3 id="_preparing_release">准备一次发布</h3>
<div class="paragraph">
<p>
现在你可以发布一个构建了。
其中一件事情就是为那些不使用 Git 的可怜包们创建一个最新的快照归档。
使用 <code>git archive</code> 命令完成此工作：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git archive master --prefix='project/' | gzip &gt; `git describe master`.tar.gz
$ ls *.tar.gz
v1.6.2-rc1-20-g8c5b85c.tar.gz</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果有人将这个压缩包解压，他就可以在一个 <code>project</code> 目录中得到你项目的最新快照。
你也可以以类似的方式创建一个 zip 压缩包，但此时你应该向 <code>git archive</code> 命令传递 <code>--format=zip</code> 选项：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git archive master --prefix='project/' --format=zip &gt; `git describe master`.zip</code></pre>
</div>
</div>
<div class="paragraph">
<p>现在你有了本次发布的一个 tar 包和一个 zip 包，可以将其上传到网站或以电子邮件的形式发送给人们。</p>
</div>
</div>
<div class="sect3">
<h3 id="_the_shortlog">制作提交简报</h3>
<div class="paragraph">
<p>
现在是时候通知邮件列表里那些好奇你的项目发生了什么的人了。
使用 <code>git shortlog</code> 命令可以快速生成一份包含从上次发布之后项目新增内容的修改日志（changelog）类文档。
它会对你给定范围内的所有提交进行总结；比如，你的上一次发布名称是 v1.0.1，那么下面的命令可以给出上次发布以来所有提交的总结：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git shortlog --no-merges master --not v1.0.1
Chris Wanstrath (6):
      Add support for annotated tags to Grit::Tag
      Add packed-refs annotated tag support.
      Add Grit::Commit#to_patch
      Update version and History.txt
      Remove stray `puts`
      Make ls_tree ignore nils

Tom Preston-Werner (4):
      fix dates in history
      dynamic version method
      Version bump to 1.0.2
      Regenerated gemspec for version 1.0.2</code></pre>
</div>
</div>
<div class="paragraph">
<p>这份整洁的总结包括了自 v1.0.1 以来的所有提交，并且已经按照作者分好组，你可以通过电子邮件将其直接发送到列表中。</p>
</div>
</div>
<div id="nav"><a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%90%91%E4%B8%80%E4%B8%AA%E9%A1%B9%E7%9B%AE%E8%B4%A1%E7%8C%AE">prev</a> | <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E6%80%BB%E7%BB%93">next</a></div></div>
</div>

        </div>
      </div>
      <footer>
  <div class="site-source">
    <a href="/site">About this site</a><br>
    Patches, suggestions, and comments are welcome.
  </div>
  <div class="sfc-member">
    Git is a member of <a href="/sfc">Software Freedom Conservancy</a>
  </div>
</footer>
<a href="#top" class="no-js scrollToTop" id="scrollToTop" data-label="Scroll to top">
  <img src="/images/icons/chevron-up@2x.png" width="20" height="20" alt="scroll-to-top"/>
</a>
<script src="/assets/application-b09f91f7c527919e4bc194769429065537d64a7f73b9fe93b107afef32b02939.js"></script>

    </div>

</body>
</html>
